import 'dart:async';
import 'dart:io';
import 'dart:math';
import 'dart:typed_data';

import 'package:android_intent_plus/android_intent.dart';
import 'package:elevator/get/intl_keys.dart';
import 'package:elevator/model/alerm_info.dart';
import 'package:elevator/model/build_detail.dart';
import 'package:elevator/model/build_info.dart';
import 'package:elevator/model/lift_info.dart';
import 'package:elevator/model/tcp_info.dart';
import 'package:flutter/scheduler.dart';
import 'package:mqtt_client/mqtt_client.dart';
import 'package:mysql1/mysql1.dart' as mysql;
import 'package:flutter/material.dart';
import 'package:flutter_app_badger/flutter_app_badger.dart';
import 'package:permission_handler/permission_handler.dart';
import 'package:typed_data/typed_data.dart';

import 'package:get/get.dart';
import 'package:mysql1/mysql1.dart';
import 'package:umeng_push_sdk/umeng_push_sdk.dart';

import '../../../model/notification_info.dart';
import '../../../model/pum_info.dart';
import '../../../model/pus_info.dart';
import '../../../model/user.dart';
import '../../../mqtt/constant.dart';
import '../../../mqtt/mqtt_call_back.dart';
import '../../../mqtt/mqtt_manager.dart';
import '../../../utils/eventbus.dart';
import '../../../utils/mynotification.dart';
import '../../../utils/utils_dialog.dart';
import '../../../utils/utils_umpush.dart';
import 'home_state.dart';

class HomeLogic extends GetxController {

  final HomeState state = HomeState();
  final _TAG = "HomePage";

  static const int ID_LIFT_LISTVIEW = 0x1001;

  @override
  void onInit() {
    //设置deviceToken回调
    UmengPushSdk.setTokenCallback((deviceToken) {
      print("$_TAG deviceToken:$deviceToken");
      saveToken(deviceToken);
    });

 /*   //设置自定义消息回调
    UmengPushSdk.setMessageCallback((msg) {
      print("$_TAG receive custom:" + msg);
      Get.snackbar('receive custom', "msg:" + msg,snackPosition: SnackPosition.BOTTOM);
    });*/

    //设置通知消息回调
    UmengPushSdk.setNotificationCallback((receive) async {
      print("$_TAG receive:$receive");

      state.alermNotifCount ++;
      if (await FlutterAppBadger.isAppBadgeSupported()) {
        FlutterAppBadger.updateBadgeCount(state.alermNotifCount);
      }

      /*Get.dialog(AlertDialog(
        title: Text(IntlKeys.receiveMsg.tr),
        content: SelectableText("receive Msg:$receive"),
        actions: [
          ElevatedButton(
            child: Text(IntlKeys.close.tr),
            onPressed: () {
              Get.back(); // 关闭对话框
            },
          ),
        ],
      ));*/
    }, (open) {
      print("$_TAG open:$open");
      /*Get.dialog(AlertDialog(
        title: Text(IntlKeys.receiveMsgWhenOpen.tr),
        content: Text(IntlKeys.receiveMsgWithStr.trArgs([open])),
        actions: [
          ElevatedButton(
            child: Text(IntlKeys.close),
            onPressed: () {
              Get.back(); // 关闭对话框
            },
          ),
        ],
      ));*/
    });

    registerPush();
    super.onInit();
  }

  @override
  void onReady() {
    print("$_TAG onReady---------------------------------------------------");
    ///test();
    super.onReady();

    User user = Get.arguments;
    dPrint("user:$user");
    state.user = user;
    loadInfo();
  }

  @override
  void onClose() {
    UmengPushSdk.setPushEnable(false);
    MQTTManager mqttManager = MQTTManager();
    mqttManager.disConnect();
    super.onClose();
  }

  void saveToken (String token) async{
    print("start saveToken");
    var settings = mysql.ConnectionSettings(
        host: '36.141.45.30',
        port: 43306,
        user: 'root',
        password: 'adminemqx123',
        db: 'RegInfo',
        useCompression: false,
        timeout:const Duration(seconds: 60),
        maxPacketSize:16 * 1024 * 1024 *1024,
        characterSet: CharacterSet.UTF8MB4);
    var conn;
    try{
      conn = await mysql.MySqlConnection.connect(settings);
      int sysType = Platform.isAndroid? 1:2;
      var result = await conn
          .query('update tbPassWord set tokenID=? , sysType=? where ID=?',[token,sysType,state.user.id]);
      dPrint(result!.toString());
    }catch(e){
      await conn.close();
      saveToken(token);
    }
  }

  void loadInfo(){
    if(null != state.user && null != state.user.psBuilds && state.user.psBuilds != ""){
      List<String>? buildIds = state.user.psBuilds?.split(",");
      getBuildIdInfo(buildIds!);
    }
  }

  /// 查询出用户所有的buildid对应的配置信息,加载完成后启动mqtt连接，连接成功后开启订阅
  ///
  void getBuildIdInfo(List<String> buildIds) async {
    await Future.forEach(buildIds,(buildId) async{
      queryBuildIdInfo(buildId).then((buildInfo) => {
        state.buildInfoMap[buildId] = buildInfo,
        bus.emit(bus.buildInfoKey, buildInfo),
        dPrint("建筑：$buildId 加载完成，$state.buildInfoMap"),
        state.buildList.add(buildInfo),
        if(state.buildList.length==1){
          selectIdBuildChanged(0)
        }
        //state.loadBuildInfo()
      },onError: (e){
        dPrint("加载楼盘信息出现异常：$e");
      });
    }).whenComplete(() => {
      initState(),
      dPrint("开始初始化mqtt"),
      startConnectMqtt(),
      dPrint("mqtt初始化完成")
    });
  }

  ///APP进入后台监听器
  late final AppLifecycleListener _listener;
  late AppLifecycleState? _state;
  bool appShow = true;

  ///每隔30秒检测一次电梯列表状态定时器
  late Timer periodicTimer;

  void initState() {
    _state = SchedulerBinding.instance.lifecycleState;
    _listener = AppLifecycleListener(
      onShow: () => _handleTransition('show'),
      onResume: () => _handleTransition('resume'),
      onHide: () => _handleTransition('hide'),
      onInactive: () => _handleTransition('inactive'),
      onPause: () => _handleTransition('pause'),
      onDetach: () => _handleTransition('detach'),
      onRestart: () => _handleTransition('restart'),
    );

    periodicTimer = Timer.periodic(
      const Duration(seconds: 30),//每隔30秒检测一次电梯列表状态
          (timer) {
            state.checkClearState();
      },
    );
  }

  void _handleTransition(String state) {
    if(identical("show",state)){
      appShow = true;
      clearAlermNotification();
    }else if(identical("hide",state)){
      appShow = false;
    }else if(identical("resume",state)){

    }else if(identical("restart",state)){

    }
    dPrint("界面状态改变： $state");
    debugPrint("PageHomeLogic: stateChanged: $state");
  }

  Future queryBuildIdInfo(String buildId) async {
    dPrint("start queryBuildIdInfo $buildId");
    var settings = mysql.ConnectionSettings(
        host: '36.141.45.30',
        port: 43306,
        user: 'root',
        password: 'adminemqx123',
        db: 'liftdb_$buildId',
        useCompression: false,
        timeout:const Duration(seconds: 60),
        maxPacketSize:16 * 1024 * 1024 *1024,
        characterSet: CharacterSet.UTF8MB4);
    var conn = await mysql.MySqlConnection.connect(settings);

    BuildInfo buildInfo = BuildInfo();
    buildInfo.buildId = buildId;

    var buildDetailList = await conn
        .query('select * from tbliftbaseinfo');
    buildInfo.loadBuildDetail(buildDetailList);

    var liftList = await conn
        .query('select * from tbappliftCfg');
    buildInfo.loadLiftInfo(liftList);

    var fnInfoList = await conn
        .query('select * from tbappcfginfo');
    buildInfo.loadFnInfo(fnInfoList);

    var warnInfoList = await conn
        .query('select * from tbapplwarncfg');
    buildInfo.loadWarnInfo(warnInfoList);

    var eWarnInfoList = await conn
        .query('select * from tbappelwarncfg');
    buildInfo.loadEWarnInfo(eWarnInfoList);

    var tpccfgList = await conn
        .query('select * from tbtpccfg');
    buildInfo.loadTpcCfg(tpccfgList);

    var pumcfgList = await conn
        .query('select * from tbpumcfg');
    buildInfo.loadPumCfg(pumcfgList);

    var puscfgList = await conn
        .query('select * from tbpuscfg');
    buildInfo.loadPusCfg(puscfgList);

    var group1List = await conn
        .query('select * from tbappgroup1');
    buildInfo.loadGroupInfo(1,group1List);
    var group2List = await conn
        .query('select * from tbappgroup2');
    buildInfo.loadGroupInfo(2,group2List);
    var group3List = await conn
        .query('select * from tbappgroup3');
    buildInfo.loadGroupInfo(3,group3List);
    var group4List = await conn
        .query('select * from tbappgroup4');
    buildInfo.loadGroupInfo(4,group4List);
    var group5List = await conn
        .query('select * from tbappgroup5');
    buildInfo.loadGroupInfo(5,group5List);
    var group6List = await conn
        .query('select * from tbappgroup6');
    buildInfo.loadGroupInfo(6,group6List);
    var group7List = await conn
        .query('select * from tbappgroup7');
    buildInfo.loadGroupInfo(7,group7List);
    var group8List = await conn
        .query('select * from tbappgroup8');
    buildInfo.loadGroupInfo(8,group8List);
    var group9List = await conn
        .query('select * from tbappgroup9');
    buildInfo.loadGroupInfo(9,group9List);

    await conn.close();
    return Future.value(buildInfo);
  }

  ///退出逻辑处理，两秒内不退出应用
  Future<bool> willPop() async {
    if (Platform.isAndroid) {
      const intent = AndroidIntent(
          action: "android.intent.action.MAIN",
          flags: [0x10000000],
          category: "android.intent.category.HOME");
      intent.launch();
      return false;
    }
    return true;
  }

  selectIdBuildChanged(int index){
    state.selectIdBuildChanged(index);
    state.allLiftList.clear();
    update([ID_LIFT_LISTVIEW]);
  }

  void selectIdGroupChanged(int index) {
    state.selectIdGroupChanged(index);
    state.allLiftList.clear();
    update([ID_LIFT_LISTVIEW]);
  }

  //点击所有按钮
  clickAll(BuildContext context) {
    state.allLiftList.clear();
    state.allLiftList.addAll(state.selectBuildInfo.value.liftInfoStateMaps.values);
    update([ID_LIFT_LISTVIEW]);
  }

  //点击搜索按钮
  clickSearch(BuildContext context) { Get.toNamed("/search",arguments: {"buildList":state.buildList,"psAuth":state.user.psAuth,"user":state.user});}

  void goToSettingPage() { Get.toNamed("/setting",arguments: {"user":state.user});}

  ///清楚APP图标小红点
  void clearAlermNotification() {
    state.alermNotifCount = 0;
    FlutterAppBadger.removeBadge();
  }


  late MQTTManager mqttManager;
  void startConnectMqtt(){
    if(null!=state.user && null!=state.user.psBuilds && state.user.psBuilds != ""){
      List<String> builds = [];
      if(state.user.psBuilds!.contains("/")){
        builds.addAll(state.user.psBuilds!.split("/"));
      }else{
        builds.add(state.user.psBuilds!);
      }
      mqttManager = MQTTManager();
      mqttManager.clentId = state.user.psName!;
      mqttManager.callBack = MqttCallBack(onConnected, onDisconnected, onSubscribed
          , onSubscribeFail, onUnsubscribed, onMessaged,pong);
      mqttManager.connect();
    }
  }

  // 连接成功
  void onConnected() {
    MQTTManager mqttManager = MQTTManager();
    if(null!=state.user && null!=state.user.psBuilds && state.user.psBuilds != ""){
      List<String>? builds = state.user.psBuilds?.split(",");
      for(String buildId in builds!){
        mqttManager.subscribe(Constant.TOPIC_QUERY_SVP + buildId, MqttQos.atLeastOnce);
        mqttManager.subscribe(Constant.TOPIC_QUERY_TPC + buildId, MqttQos.atLeastOnce);
      }
    }
  }

  void onMessaged(String topic,Uint8Buffer byteBuffer){
    dPrint("onMessaged：$topic -------------");
    if(topic.isNotEmpty){
      if(topic.startsWith(Constant.TOPIC_QUERY_SVP)){
        parseSvp(topic,byteBuffer);
      }else if(topic.startsWith(Constant.TOPIC_QUERY_TPC)){
        parseTpc(topic,byteBuffer);
      }
    }
  }

  void parseSvp(String topic,Uint8Buffer byteBuffer){
    int buildIdIndex = topic.lastIndexOf("/");
    String buildId = topic.substring(buildIdIndex+1);
    List<int> byteList = byteBuffer.toList();
    if(byteList.length>8 && byteList.first == 0xA5 && byteList.last == 0x17){
      BuildInfo buildInfo;
      if(state.buildInfoMap.containsKey(buildId)){
        buildInfo = state.buildInfoMap[buildId]!;
      }else{
        return;
      }
      buildInfo.buildId = buildId;
      dPrint("收到电梯$topic状态信息-------------");
      int index = 1;
      int length = byteList.elementAt(index);
      index++;
      int type = byteList.elementAt(index);
      index++;
      int com = byteList.elementAt(index);
      index++;
      int num = byteList.elementAt(index);
      dPrint("电梯$topic总长：${byteList.length},包长：$length,num:$num");

      for(int i=0;i<num;i++){
        int order = (com - 1) * 6 + i + 1;
        index++;
        ///电梯开关状态
        int switchState = byteList.elementAt(index);
        index++;
        ///电梯上、落状态
        int currentState = byteList.elementAt(index);
        index++;
        ///电梯当前所在楼层代码
        int currentAddr = byteList.elementAt(index);
        index++;
        int data = byteList.elementAt(index) * 100;
        index++;
        data = data + byteList.elementAt(index) * 10;
        index++;
        data = data + byteList.elementAt(index);
        index++;
        int alerm1 = byteList.elementAt(index);
        index++;
        int alerm2 = byteList.elementAt(index);
        index++;
        int alerm3 = byteList.elementAt(index);
        index++;
        int alerm4 = byteList.elementAt(index);

        if(buildInfo.liftInfoStateMaps.containsKey(order)){
          LiftInfo liftInfo = buildInfo.liftInfoStateMaps[order]!;
          if(null != liftInfo.liftName && liftInfo.liftName.isNotEmpty){
            dPrint("svp:read to update----------------");
            liftInfo.currentAddr = buildInfo.getLiftAddr(currentAddr);
            liftInfo.currentState = buildInfo.getLiftState(currentState);
            liftInfo.spvAlermList = buildInfo.getSpvAlermInfo(liftInfo,alerm1,alerm2,alerm3,alerm4);
            buildInfo.loadAlermInfo(liftInfo);
            alermCheck(200,buildId,liftInfo,buildInfo.buildDetail.buildNumber);
            liftInfo.updateState();
            buildInfo.liftInfoStateMaps[order] = liftInfo;
            bus.emit('${bus.liftInfo_Key}${buildId}_$order', liftInfo);
            dPrint("svp:UPDATE:$liftInfo ++++++++++++");
          }
        }
      }
      state.buildInfoMap[buildId] = buildInfo;
      update([ID_LIFT_LISTVIEW]);
      bus.emit(bus.buildInfoKey, buildInfo);
      dPrint("SVP:$topic：$buildInfo");
    }else{
      dPrint("电梯$buildId状态信息解析错误-------------");
    }
  }

  void parseTpc(String topic,Uint8Buffer byteBuffer){
    int buildIdIndex = topic.lastIndexOf("/");
    String buildId = topic.substring(buildIdIndex+1);

    if(byteBuffer.length==230 && byteBuffer.first == 0xA5 && byteBuffer.last == 0x17){
      BuildInfo buildInfo;
      if(state.buildInfoMap.containsKey(buildId)){
        buildInfo = state.buildInfoMap[buildId]!;
      }else{
        return;
      }

      int index = 1;
      int length = byteBuffer.elementAt(index);
      index++;
      int type = byteBuffer.elementAt(index);
      index++;
      int currentAddr = byteBuffer.elementAt(index);
      dPrint("收到电梯$topic状态信息-------------$currentAddr");
      index++;
      Iterable<int> dayList = byteBuffer.getRange(index, index+128);
      String day = String.fromCharCodes(dayList);
      index+=128;
      Iterable<int> versionList= byteBuffer.getRange(index, index+32);
      String version = String.fromCharCodes(versionList);
      index+=32;
      String result = bytePrintAsString(byteBuffer);
      Iterable<int> elevatoDataList= byteBuffer.getRange(index, index+63);
      List<AlermInfo> tpcAlermList = [];
      if(null != buildInfo.tpcInfoMap && buildInfo.tpcInfoMap.isNotEmpty){
        for(int key in buildInfo.tpcInfoMap.keys){
          List<TpcInfo>? tpcInfoList = buildInfo.tpcInfoMap[key];
          if(null != tpcInfoList && tpcInfoList.isNotEmpty){
            int tpcIndex = key - 0x300;
            if(tpcIndex>=0 && tpcIndex<elevatoDataList.length){
              int tpc = elevatoDataList.elementAt(tpcIndex);
              String tpcBuffer = BuildInfo.reversedStr(BuildInfo.intToRadixString(tpc));
              for(TpcInfo tpcInfo in tpcInfoList){
                if(tpcInfo.tpcAddrBit>=0 && tpcInfo.tpcAddrBit<tpcBuffer.length
                    && 0=="1".compareTo(tpcBuffer.substring(tpcInfo.tpcAddrBit,tpcInfo.tpcAddrBit+1))){
                  AlermInfo alermInfo = AlermInfo.buildFormTpcInfo(tpcInfo);
                  tpcAlermList.add(alermInfo);
                }
              }
            }
          }
        }
      }

      String dls2 = buildInfo.intToRadix16String(elevatoDataList.elementAt(0x327-0x300));
      String dls1 = buildInfo.intToRadix16String(elevatoDataList.elementAt(0x328-0x300));
      String dlsStr = "0x$dls1$dls2";
      var dls = int.tryParse(dlsStr);

      String lds2 = buildInfo.intToRadix16String(elevatoDataList.elementAt(0x329-0x300));
      String lds1 = buildInfo.intToRadix16String(elevatoDataList.elementAt(0x32A-0x300));
      String ldsStr = "0x$lds1$lds2";
      var lds = int.tryParse(ldsStr);

      String pulse2 = buildInfo.intToRadix16String(elevatoDataList.elementAt(0x32C-0x300));
      String pulse1 = buildInfo.intToRadix16String(elevatoDataList.elementAt(0x32D-0x300));
      String pulseStr = "0x$pulse1$pulse2";
      var pulse = int.tryParse(pulseStr);

      String speed2 = buildInfo.intToRadix16String(elevatoDataList.elementAt(0x332-0x300));
      String speed1 = buildInfo.intToRadix16String(elevatoDataList.elementAt(0x331-0x300));
      String speedStr = "0x${speed2}${speed1}";
      var speed = int.tryParse(speedStr);
      int load = elevatoDataList.elementAt(0x324-0x300);

      int elevatoIndex = 0;
      elevatoIndex+=2;
      int pus1 = elevatoDataList.elementAt(elevatoIndex);
      elevatoIndex++;
      int pus2 = elevatoDataList.elementAt(elevatoIndex);
      elevatoIndex+=2;
      elevatoIndex++;
      int pum1 = elevatoDataList.elementAt(elevatoIndex);
      elevatoIndex++;
      int pum2 = elevatoDataList.elementAt(elevatoIndex);
      elevatoIndex++;

      PusInfo? pusInfo;

      PumInfo? puwInfo;

      if(null != buildInfo.pusInfoMap && buildInfo.pusInfoMap.isNotEmpty){
        if(!(pus1==0 && pus2==0) && !(pus1==255 && pus2==255)){
          String pusCodeStr = "${buildInfo.intToRadix16String(pus2)}${buildInfo.intToRadix16String(pus1)}";
          int pusCode = int.parse(pusCodeStr,radix: 16);
          if(buildInfo.pusInfoMap.containsKey(pusCode)){
            pusInfo = buildInfo.pusInfoMap[pusCode];
            AlermInfo alermInfo = AlermInfo.buildFormPusInfo(buildInfo.pusInfoMap[pusCode]!);
            tpcAlermList.add(alermInfo);
          }
        }
      }

      if(null != buildInfo.pumInfoMap && buildInfo.pumInfoMap.isNotEmpty){
        if(!(pum1==0 && pum2==0) && !(pum1==255 && pum2==255)){
          String pumCodeStr = "${buildInfo.intToRadix16String(pum2)}${buildInfo.intToRadix16String(pum1)}";
          int pumCode = int.parse(pumCodeStr,radix: 16);
          if(buildInfo.pumInfoMap.containsKey(pumCode)){
            puwInfo = buildInfo.pumInfoMap[pumCode];
            AlermInfo alermInfo = AlermInfo.buildFormPumInfo(buildInfo.pumInfoMap[pumCode]!);
            tpcAlermList.add(alermInfo);
          }
        }
      }
      index+=63;

      if(buildInfo.liftInfoStateMaps.containsKey(currentAddr)){
        LiftInfo liftInfo = buildInfo.liftInfoStateMaps[currentAddr]!;
        liftInfo.day = day;
        liftInfo.version = version;
        if(null!=dls){
          liftInfo.dls = dls.toString();
        }
        if(null!=lds){
          liftInfo.lds = lds.toString();
        }
        if(null!=pulse){
          liftInfo.pulse = pulse.toString();
        }
        if(0==liftInfo.liftType){///普通梯 速度 负载赋值
          if(null!=speed){
            liftInfo.speed = speed;
          }
          liftInfo.load = load;
        }
        liftInfo.tpcAlermList = tpcAlermList;
        liftInfo.pusInfo = pusInfo;
        liftInfo.puwInfo = puwInfo;
        buildInfo.loadAlermInfo(liftInfo);
        alermCheck(100,buildId,liftInfo,buildInfo.buildDetail.buildNumber);
        liftInfo.updateState();
        bus.emit('${bus.liftInfo_Key}${buildId}_${liftInfo.order}', liftInfo);
        buildInfo.liftInfoStateMaps[currentAddr] = liftInfo;
        buildInfo.buildId = buildId;
        state.buildInfoMap[buildId] = buildInfo;
        liftInfo.elevatoDataList = elevatoDataList;
      }
      dPrint("TPC:$topic：$buildInfo");
    }else{
      dPrint("电梯$buildId状态信息解析错误-------------");
    }
  }

  // 连接断开
  void onDisconnected() {
    dPrint("mqtt连接断开---------");
  }

  // 订阅主题成功
  void onSubscribed(String topic) {
    dPrint("订阅主题成功 onSubscribed：$topic -------------");
  }

  // 订阅主题失败
  void onSubscribeFail(String topic) {
    dPrint("订阅主题失败 onSubscribeFail：$topic -------------");
  }

  // 成功取消订阅
  void onUnsubscribed(String? topic) {

  }

  // 收到 PING 响应
  void pong() {

  }

  Map<String,NotificationInfo> alermNotifMaps = {};
  int alermNotifCount = 0;

  /// 检查警告信息是否需要发送通知栏
  void alermCheck(int type,String buildId,LiftInfo liftInfo, String buildNumber){
    if(null!=liftInfo){
      if(!appShow && liftInfo.alermList.isNotEmpty){
        for(AlermInfo alermInfo in liftInfo.alermList){
          NotificationInfo notificationInfo = NotificationInfo(buildId, alermInfo.number, alermInfo.sName, alermInfo.type, liftInfo.liftName, liftInfo.order,buildNumber);
          String key = notificationInfo.getKey();
          if( null==alermNotifMaps[key]){
            alermNotifMaps[key] = notificationInfo;
            showNotification(type, notificationInfo);
          }
        }
      }else{
        String liftKey = NotificationInfo.getLiftKey(buildId,liftInfo.liftName, liftInfo.order);
        alermNotifMaps.removeWhere((key, value) => key.startsWith(liftKey));
      }
    }
  }

  Future<void> showNotification(int type, NotificationInfo notificationInfo) async {
    if(!appShow){
      alermNotifCount ++;
      if ( await FlutterAppBadger.isAppBadgeSupported()) {
        FlutterAppBadger.updateBadgeCount(alermNotifCount);
      }
      if (Platform.isAndroid) {
        if ( await Permission.notification.request().isGranted) {
          sendNotification(type, notificationInfo);
        }else{
          dPrint("isGranted false");
          //打开应用设置
          final flag = await UtilsDialog.showSingleNoticeDialog(Get.context!, "请打开设置，勾选通知权限");
          if(flag != null && flag){
            openAppSettings();
          }
        }
      } else {
        sendNotification(type, notificationInfo);
      }

    }
  }

  var notification = MyNotification();
  void sendNotification(int type, NotificationInfo notificationInfo) {
    dPrint("isGranted true");
    //点击发送通知
    Map params = {};
    params['type'] = type;
    params['content'] = "content";
    int rid = int.parse(_randomBit(9));
    notification.send("警告", notificationInfo.getContent(),notificationId: rid, params: notificationInfo.toString());
  }

  _randomBit(int len) {
    String scopeF = '123456789'; //首位
    String scopeC = '0123456789'; //中间
    String result = '';
    for (int i = 0; i < len; i++) {
      if (i == 0) {
        result = scopeF[Random().nextInt(scopeF.length)];
      } else {
        result = result + scopeC[Random().nextInt(scopeC.length)];
      }
    }  return result;
  }

  bool debug = false;
  dPrint(String msg){
    if(debug) debugPrint(msg);
  }

  String bytePrintAsString(Uint8Buffer byteArray) {
    StringBuffer buf = StringBuffer();
    for (int i = 0; i < byteArray.length; i++) {
      String hex = byteArray.elementAt(i).toRadixString(16);
      buf.write("$hex ");
    }
    dPrint(buf.toString().toUpperCase());
    return buf.toString();
  }

}
